#ifndef MAP_H
#define MAP_H

#include"vertex.h"
#include"edge.h"
#include<QFile>
#include <QTextStream>
#include <QCryptographicHash>
#include<vector>
#include <unordered_map>
#include <utility>
#include <limits>
#include<queue>


class Map
{
public:
    Map();
    ~Map();  // 添加析构函数

    struct pair_hash {
        template <class T1, class T2>
        std::size_t operator () (const std::pair<T1,T2> &p) const {
            auto h1 = std::hash<T1>{}(p.first);
            auto h2 = std::hash<T2>{}(p.second);
            return h1 ^ h2;
        }
    };

    //用来查询最近的100个点的数据成员
    std::vector<Edge*> visibleEdges; // 当前可见的边
    Vertex* currentTarget = nullptr; // 当前目标点
    std::vector<Vertex*> currentNearVertices; // 最近的顶点
    bool showAllEdges = true; // 初始显示所有边

 std::vector<Edge*> findShortestPath(int startId, int endId);//最短路径
std::unordered_map<int, Vertex*> vertexIdMap;
    // 数据访问接口
    const std::vector<Vertex*>& getVertices() const { return vertices; }
    const std::vector<Edge*>& getEdges() const { return edges; }


    std::unordered_map<std::pair<int, int>, Vertex*, pair_hash> gridRepresentative;
    void setCurrentcenter(const QString& currentAddress);
    void generatemap(int numVertex);
    QPointF getVertexPosition(int id) const;

    //找最近的100个   

    double gridSize = 200.0;
    void buildGridIndex();
    std::unordered_map<std::pair<int, int>, std::vector<Edge*>, pair_hash> gridIndex;

    void dijkstra(Vertex* source, std::unordered_map<Vertex*, double>& dist,std::unordered_map<Vertex*, Edge*>& prev);
    void findNear(float xx, float yy, int count);
    void resetDisplay();//用来显示最近的100个点时更改状态的

private:
    // 地图生成相关方法
    void generateVertices(int numV);
    void addEdgeMST();
    void connectEdges(int minEdgesPerVertex);
    int findParent(std::vector<int>& parent, int i);
    void unionSets(std::vector<int>& parent, int x, int y);
    //std::vector<Edge*>shortestLen(Vertex*a,Vertex*b);

    // 数据存储
    std::vector<Vertex*> vertices;
    std::vector<Edge*> edges;


    // 城市布局参数
    const double CITY_CENTER_RATIO = 0.15;
    const double AREA_RATIO = 0.0269;
    const double AVG_AREA = 100;
    double centerX = 500, centerY = 500;
    double cityRadius;

};
#endif // MAP_H
